#include "iostream"
#include <fstream>
#include "protobuf.pb/contacts.pb.h"
#include "protobuf.pb/Phone.pb.h"


void AddPeopleInfo(Ctct::PeopleInfo* person)
{
    person->set_age(16);
    person->set_name("Alice");
    Phone::Phone* phonenum =  person->add_phonenum();

    //内部消息类，用的时下划线表示
    phonenum->set_pdtype(Phone::Phone_PhoneType::Phone_PhoneType_MOBILE);    
    phonenum->set_number("12312");


    Ctct::Addr addr;
    addr.set_home_addr("id");
    addr.set_word_addr("iq");
    
    //mutable会给对应类型开辟空间，返回该类型开辟空间后的指针
    //PackFrom会让any转换成该类型,该函数有返回值，用于判断转换成功与否
    person->mutable_addr_data()->PackFrom(addr);


    //oneof设置
    //这里添加学历,只能选择一个
    //返回值是枚举变量，EducationalBackgroundCase，其在没有设置的常量设置的是0;
    person->clear_educational_background();
    if(person->educational_background_case() == Ctct::PeopleInfo::EducationalBackgroundCase::EDUCATIONAL_BACKGROUND_NOT_SET)
    {
        person->set_college(1);
        std::cout<<"学历添加成功"<<std::endl;
    }
    //利用指针赋值
    person->mutable_remark()->operator[]("ALice")  ="测试联系人";
    std::cout<<"Success Add\n";
}

int main()
{
    //验证版本，
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    std::fstream fs("Contacts.bin",std::ios::binary | std::ios::app | std::ios::out|std::ios::in);
    if(!fs.is_open())
    {
        std::cerr<<"文件打开失败\n";
    }
    Ctct::Contacts ctct;
    if(!ctct.ParseFromIstream(&fs))
    {
        std::cout<<"反序列化失败\n";
    }
    AddPeopleInfo(ctct.add_personinfo());


    // fs.close();
    // fs.open("Contacts.bin",std::ios::binary | std::ios::app | std::ios::out|std::ios::in);
    std::cout<<fs.bad()<<fs.eof()<<std::endl;
    //C++的fstream在读取之后呢，会设置eof，因此需要clear清楚
    fs.clear();
    std::cout<<fs.bad()<<fs.eof()<<std::endl;
    if(!ctct.SerializePartialToOstream(&fs))
    {
        std::cout<<"序列化失败\n";
    }
    std::cout<<"写入·文件\n";
    fs.close();

    google::protobuf::ShutdownProtobufLibrary();


    return 0;
}